#include "debug.h"
#include "../DDIC/AllDDIC.h"

#include "OuadSPI.h"
/* 合肥定义通用 下位机读写接口

*/

extern u8  USB_Rx_Demura_End_Flag; //Demura数据全部完成标志
extern u8  DemuraIctype;  		  //识别IC型号
extern u8  Demura_OLEDModule_flag;//同型DDIC下的衍生项目
extern u8  Demura_send_flag;
extern u8  DemuraSize_H8;
extern u8  DemuraSize_L8;

//extern u32 Demura_START_FLAG;  //Demura 数据传输开始标志

 u32 HF_DemuraRecivedNum=0;      //统计已经接收的数据数量
extern u32  USB_DemuraParament_Num;
extern u32 Demura_START_FLAG;  //Demura 数据传输开始标志
extern u32 Demura_Pre_FLAG;    //谱瑞demura配置文件开始标志

//read solomen 2828  register
void HF_SSD_Write(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer)
{  
		u16 offerset=4;	
 	u16 i=0;u16 PackNum=0;u8 Reg=0;
//	u16 Value=0;
		PackNum=buffer[2];
	  Reg=buffer[3];
    SSD2828_W_Cmd(SigMode ,channel,Reg);
    if(SigMode == Video_Mode)
    {
        for (i=0;i<PackNum-1;i++)
				{					
					SPI_Write_u8_Data(SPI3_Mode,channel,buffer[i+offerset]);
				}
    }
		else if(SigMode == CMD_Mode)
    {
		
			#ifdef SSD_Command_16	
			 for (i=0;i<(PackNum-1)/2;i++)
				{			
					
		//			 MCU_2832_Write_Data(channel,(buffer[2*i+1+offerset]|buffer[2*i+offerset]));
					
					SSD2828_W_Data(SigMode ,channel,(buffer[2*i+1+offerset]|buffer[2*i+offerset]));
			  //MCU_2832_Write_Data(channel,buffer[2*i+1+offerset]|buffer[2*i+offerset]);
					
					  
				}
		#else
			for (i=0;i<PackNum-1;i++)
				{					
					 MCU_2832_Write_Data(channel,buffer[i+offerset]);
				}
		#endif
    }
		else if((SigMode == SPI3_Mode)||(SigMode == SPI4_Mode)) 
		{
	//        SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Value));
	//        SSD2828_W_Data(SigMode ,channel,(u8)(Value>>8));	
		}
		
		buffer[1] = buffer[1]+1;

    STM2PC(pdev,CDC_IN_EP,buffer,PackNum+3);     
}


//read solomen 2828  register
void HF_SSD_Read(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer)
{
		u16 offerset=4;	
	u16 i=0;u16 PackNum=0;u8 Reg=0;
//	u16 Value=0;
		PackNum=buffer[2];
	  Reg=buffer[3];
	
    SSD2828_W_Cmd(SigMode ,channel,Reg);
    if(SigMode == Video_Mode)
    { // SSD2828_W_Cmd(SigMode ,channel,Reg);
					for (i=0;i<PackNum-1;i++)
				{					
					delay_us(3);
					buffer[i+offerset] = (SPI3_Read_u8_Data(channel)& 0xFF);
				}			
    }
    else if(SigMode == CMD_Mode)
    {      
				#ifdef SSD_Command_16	
					 for (i=0;i<(PackNum-1)/2;i++)
						{					
							buffer[2*i+offerset]=SSD2828_R_Data(SigMode ,channel)&0xff;
							buffer[2*i+offerset+1]=(SSD2828_R_Data(SigMode ,channel)>>8);
						}
				#else
					for (i=0;i<PackNum-1;i++)
						{				
							buffer[i+offerset]=SSD2828_R_Data(SigMode ,channel)&0xff;	
						}
				#endif
    }
				
			buffer[1] = buffer[1]+1;
			STM2PC(pdev,CDC_IN_EP,buffer,PackNum+3);     
}


void HF_MIPI_Write(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{//video mode and CMd  mode
		u16 offerset=3;
		u16 i=0;u16 PackNum=0;
	  u8 Reg=0;
		PackNum=buffer[2];
	  Reg=buffer[3];
	  SSD2828_W_Reg(SigMode,channel,0xB7,(HS_B7_Data|0x0010)&0XFFfd);
		SSD2828_W_Reg(SigMode ,channel,0xBC, PackNum);
		SSD2828_W_Reg(SigMode ,channel,0xBD, 0x0000);
		SSD2828_W_Cmd(SigMode ,channel,0xBF);	
		
		if(SigMode == Video_Mode)
		{    
			SSD2828_W_Data(SigMode ,channel,Reg);
			if(PackNum>1)
			{
				for(i = 1; i < PackNum; i++)
				{
					SSD2828_W_Data(SigMode ,channel,buffer[i+offerset]);
				}

			}
		}
		else if(SigMode == CMD_Mode)
		{  
			#ifdef SSD_Command_16	
					SSD2828_W_Data(SigMode ,channel,(buffer[1+offerset]<<8)+buffer[offerset]);
					for(i = 0; i < (((PackNum-2)/2)+((PackNum-2)%2)); i++)
					{
						SSD2828_W_Data(SigMode ,channel,(buffer[3+i*2+offerset]<<8)+buffer[2+i*2+offerset]);
					}
			#else
					SSD2828_W_Data(SigMode ,channel,buffer[offerset]);
					for(i = 1; i < PackNum; i++)
					{
						SSD2828_W_Data(SigMode ,channel,buffer[i+offerset]);
					}
			#endif
		}
    delay_ms(5);
    SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);
		
			buffer[1] = buffer[1]+1;
			STM2PC(pdev,CDC_IN_EP,buffer,PackNum+3); //+1 校验 
}
/* mipi read include video mode and cmd mode
para0 :	SigMode MIPI模式
para1 :	channel port
--------------------------
para2 :	reg 目标回读寄存器
para3 ：backnum 回读个数
para4 ：Rxbuffer 缓存回读数据的数组的指针
*/
void HF_mipi_Read_fun(u8 SigMode ,u8 channel,u8 reg ,u8 backnum, u8* Rxbuffer)
{
		u16 tmp=0;
		u8 buffer1[3];
		SSD2828_W_Reg(SigMode,channel,0xC1,backnum); //return package size                                
		SSD2828_W_Reg(SigMode,channel,0xC0,0x0001); //reset
		buffer1[0] = 0x01;
		buffer1[1] = reg; 	//Download register
		SSD2828_W_Array(SigMode,channel,buffer1,0);
		delay_ms(5); 	
		if(SigMode == Video_Mode)
		{				
			SSD2828_W_Reg(SigMode,channel,0xD4,0x00FA);
			SSD2828_W_Cmd(SigMode,channel,0xFF);
			for(i=0;i<backnum;i++)  //readback num
			{
				SSD2828_W_Cmd(SigMode,channel,0xFA);
				tmp=SPI3_Read_u16_Data(channel);
				Rxbuffer[i]=tmp>>8;
				Rxbuffer[1+i]=tmp;
				delay_ms(5);
				i++;
			}
		}
		else if(SigMode == CMD_Mode)
		{		
			SSD2828_W_Cmd(SigMode,channel,0xFF);
			for(i=0;i<backnum;i++)  //readback num
			{
				if(i==0)
					tmp=SSD2828_R_Reg(SigMode,channel,0xFF);
				else
					tmp=SSD2828_R_Reg_Flow(SigMode,channel);				
				Rxbuffer[i]=tmp;
				Rxbuffer[1+i]=tmp>>8;
				delay_ms(10);	
				i++;
			}				
		}
		else if(SigMode == SPI4_Mode)
		{
			u8 SPI_flag_bit;//SPI传递标志位
			if(SPI_flag_bit==0x01) //SPI4 读写一根线
			{
				tmp=GenR_SPI4_Read_u8_Data_3line(SigMode,channel,reg,Rxbuffer,backnum);//readback num	
			}
			else
			{
				tmp=GenR_PANEL_SPI4_Read_u8_Data(SigMode,channel,reg,Rxbuffer,backnum);//readback num
			}
		}	
}

void HF_MIPI_Read(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{	//video mode and CMd  mode
		u8 offerset=4;
    u16 PackNum=0;u8 Reg=0;u8 Read_Num=0;
    PackNum=buffer[2];
	if (PackNum>1)
	{  
		Reg=buffer[3];
		Read_Num=PackNum-1;
		
    SSD2828_W_Reg(SigMode,channel,0xB7,LP_B7_Data|0x0080);
    HF_mipi_Read_fun(SigMode,channel,Reg,Read_Num,Buffer_ReadCode); //8 bit read        
		memcpy(buffer+offerset,Buffer_ReadCode,Read_Num);
	
    SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);
		buffer[1]=buffer[1]+1; //成功cmdtype+1
	}	
	
    STM2PC(pdev,CDC_IN_EP,buffer,PackNum+3);           //返回 读取的 寄存器数据  ：ok 
}

/*
*/
/*
void HF_MIPI_Array_W(u8 SigMode ,u8 channel,u8 para[],u8 offerset)
{
	  u8 i; 
	  u8 SubNum= para[offerset-1]-1;
	  SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Long_Write);
		delay_us(100);		
		SSD2828_W_Reg(SigMode ,channel,0xBC, SubNum);
		SSD2828_W_Reg(SigMode ,channel,0xBD, 0x0000);
		SSD2828_W_Cmd(SigMode ,channel,0xBF);	
		
		if(SigMode == Video_Mode)
		{    
			//SSD2828_W_Data(SigMode ,channel,para[1+offerset]);
			for(i = 0; i < SubNum; i++)
			{
				SSD2828_W_Data(SigMode ,channel,para[i+1+offerset]);
			}
		}
		else if(SigMode == CMD_Mode)
		{  
			#ifdef SSD_Command_16	
				//MCU_2828_Write_Data(channel,(para[2+offerset]<<8)+para[1+offerset]);
				for(i = 0; i < (((SubNum )/2)+((SubNum )%2)); i++)
				{
					 MCU_2832_Write_Data(channel,(para[2+i*2+offerset]<<8)+para[1+i*2+offerset]);
				}
			#else //8bit write
				//MCU_2828_Write_Data(channel,para[1+offerset]);
				for(i = 0; i <SubNum; i++)
				{
					 MCU_2828_Write_Data(channel,para[i+1+offerset]);
				}
			#endif
		}	
		else if((SigMode == SPI3_Mode)||(SigMode == SPI4_Mode)) 
		{ 
			//SPI_Write_code(SigMode,channel,para[3],para[4]); 
			GenW_PANEL_SPI_Write_code(SigMode,channel,para);
		}			
//		if((para[0+offerset] == 1)&&(para[1] == 0x11))
//			delay_ms(70); 		
	}		

	*/
	
	
void HF_MIPI_Array_W(u8 SigMode ,u8 channel,u8 para[],u8 offerset)
{
	  u8 i; 
	  u8 SubNum= para[offerset-1]-1;
	  SSD2828_W_Reg(SigMode,channel,0xB7,LP_DCS_Long_Write);
		delay_us(100);		
		SSD2828_W_Reg(SigMode ,channel,0xBC, SubNum);
		SSD2828_W_Reg(SigMode ,channel,0xBD, 0x0000);
		SSD2828_W_Cmd(SigMode ,channel,0xBF);	
		
		if(SigMode == Video_Mode)
		{    
			//SSD2828_W_Data(SigMode ,channel,para[1+offerset]);
			for(i = 0; i < SubNum; i++)
			{
				SSD2828_W_Data(SigMode ,channel,para[i+1+offerset]);
			}
		}
		else if(SigMode == CMD_Mode)
		{  
			#ifdef SSD_Command_16	
				//MCU_2828_Write_Data(channel,(para[2+offerset]<<8)+para[1+offerset]);
				for(i = 0; i < (((SubNum )/2)+((SubNum )%2)); i++)
				{
					SSD2828_W_Data(SigMode ,channel,(para[2+i*2+offerset]<<8)+para[1+i*2+offerset]);
				}
			#else //8bit write
				//MCU_2828_Write_Data(channel,para[1+offerset]);
				for(i = 0; i <SubNum; i++)
				{
					 SSD2828_W_Data(SigMode ,channel,para[i+1+offerset]);
				}
			#endif
		}	
		else if((SigMode == SPI3_Mode) || (SigMode == SPI4_Mode))
		{
			GenW_PANEL_SPI_Write_code(SigMode,channel,para);
		}
		else if(SigMode==QuadSPI_Mode)
		{
			OSPI_Write_u8_Array(SigMode,channel , para,offerset);

		}		
	}		

	
	

//array cmd 1次通信下多条指令
void HF_ArrayCMD(USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8* buffer,u16 LP_B7_Data,u16 HS_B7_Data)
{ //[1]=0x20:	//mulit CMD can send SOLW,SOLR,DSIW,DSIR
		u16 offset=3;
		u16 j=0;u16 tem1;
	  u16 PackNum=0;
	   u8 CMDID=0;u8 Reg=0;u8 SubNum=0;
		PackNum=buffer[2];
	if (PackNum> 3)
	{ //6A 20 PN 03 14 FE 00 03 14 05 00
		u16 i=3;
		SubNum=buffer[i]; //subnum=1(CMDID)+1(Reg)+1 par+2par...(不包含subnum 本身占用byte)
		while((i<= PackNum) && (SubNum>0))//没有超过 PackNUm 同时subNum 不是0 有效
		{ 
			SubNum=buffer[i];
			offset=i+1;i=offset+SubNum; // offset 记录 CMDID 位置 ,i 记录下一笔subNUM 位置
			CMDID=buffer[offset];
			switch(CMDID)     // 偶数为从PC发给MCU, 奇数为MCU-->PC （+1 校验代表成功）
			{
			case 0x01:    //delay times->subnum=3
					delay_ms(buffer[offset+1]+buffer[offset+2]*256);
					break;
		  case 0x02:    //写solomen register [2]=PgNum(Low),[3]=Pgnum(high);[4]=CMD,[5]=PAr1,PAR2
					Reg=buffer[offset+1];
					SSD2828_W_Cmd(SigMode ,channel,Reg);
					for (j=2;j<SubNum;j++)// if send 1Reg+2par-->subnum=4
					{					
					SSD2828_W_Data(SigMode ,channel,buffer[offset+j]);
					}
						buffer[offset] = buffer[offset]+1;
					break;
			
			case 0x04:    //short 写Drive IC register 1Reg+1Par fast witer 
					HF_MIPI_Array_W(SigMode,channel,buffer,offset);//配合array data 新构建 SubNum= [offerset-1]-1;
					buffer[offset] = buffer[offset]+1;              //offset 存CMDID,off-1 存subnum,off+1存REG
					break;	
			case 0x06:    //写Drive IC register array write REG1+pAr1;REG2+PAr2
					//Reg=buffer[offset+1];
					SSD2828_W_Reg(SigMode ,channel,0xBC, 0x0002);// short type 1Reg+1par
					SSD2828_W_Reg(SigMode ,channel,0xBD, 0x0000);
					for (j=0;j<(SubNum-1)/2;j++)
					{											
					SSD2828_W_Cmd(SigMode ,channel,0xBF);	
					SSD2828_W_Data(SigMode ,channel,buffer[offset+1+j*2]);
					SSD2828_W_Data(SigMode ,channel,buffer[offset+2+j*2]);
					delay_ms(1);
						buffer[offset] = buffer[offset]+1;
					}
					break;					
		  case 0x14:  //ReadDrive IC register 
								 //SubNum=[offset-1],CMDID= [offset],Reg= [offset+1],Read1= [offset+2],Read2= [offset+3]
						Reg=buffer[offset+1];				
						SSD2828_W_Reg(SigMode,channel,0xB7,LP_B7_Data|0x0080);
						HF_mipi_Read_fun(SigMode,channel,Reg,SubNum-2,Buffer_ReadCode); //8 bit read        
						memcpy(buffer+2+offset,Buffer_ReadCode,SubNum-2);
						SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);
						buffer[offset] = buffer[offset]+1;
					break; 
			case 0x16:    //ReadDrive IC register  for short register  1register+1 par
				            //[2]=PgNum(Low),[3]=Pgnum(high);[4]=CMD,[5]=PAr1,PAR2				
						SSD2828_W_Reg(SigMode,channel,0xB7,LP_B7_Data|0x0080); 
					u8 subReadnum=buffer[offset+1]; //规律读取固定长度1 为读取1byte
				 for (j=0;j<(SubNum-1)/(subReadnum+1);j++)
						{	
							Reg=buffer[offset+2+j*2];			
						  HF_mipi_Read_fun(SigMode,channel,Reg,subReadnum,Buffer_ReadCode); //8 bit read        
						  memcpy(buffer+offset+3+j*2,Buffer_ReadCode,subReadnum);
							delay_ms(1);
						}					
						SSD2828_W_Reg(SigMode,channel,0xB7,HS_B7_Data);	
						buffer[offset] = buffer[offset]+1;
					break;	
			default:
				break;
		}			
	} //while
		buffer[1] = buffer[1]+1;
    STM2PC(pdev,CDC_IN_EP,buffer,PackNum+3);           //返回 写寄存器状态  ：ok  
		
 }	 //if
	else
	{
	STM2PC(pdev,CDC_IN_EP,buffer,PackNum+3);           //返回 写寄存器状态  ：Ng
	}
} //if



//	crc16_data = crc16(USB_Rx_Buffer,USB_Rx_Buffer[2]+3,0xFFFF);
//Cdc_core已定义[0]为 IC_ID,[2]=total_buffer, long-1byte([0])-2byte_CRC
void ProcessForIc96( USBD_HandleTypeDef *pdev,uint8_t  ep_addr,u8 SigMode ,u8 channel,u8 buffer[],u16 LP_B7_Data,u16 HS_B7_Data)//ADD BY scs
{
	switch(buffer[1]&0xFF)// %2=1PC-->MCU, %2=0 is MCU-->PC
	{	
  	case 0x00:  //panel OLED RST
			Set_panel_reset(); 
			break;
		case 0x01:    //[1]=01 delay time , [2]=PgNum(=4),[3]=delay_lo,[4]=delay_Hi
			delay_ms(buffer[3]+buffer[4]*256);
			break;
  	case 0x02:    //[1]=02 single写solomen register, [2]=PgNum(=5),[3]=SSD-reg,[4]=PAr1,[5]=PAr1,PAR2
			HF_SSD_Write(pdev,ep_addr,SigMode,channel,buffer);
			break;
		case 0x12:   //[1]=12 single读solomen register [2]=PgNum(=5),[3]=SSD-reg,[4]=PAr1,[5]=PAR2
			HF_SSD_Read( pdev,ep_addr,SigMode,channel,buffer);
			break;
		case 0x04:	//[1]=04 single写DSI_video register [2]=pgNum(>=3),[3]=Reg,[4]=PAr1,[5]=PAR2
			HF_MIPI_Write(pdev,ep_addr,SigMode ,channel,buffer, LP_B7_Data,HS_B7_Data);
			break;
 	  case 0x14:   //[1]=14 single读DSI_video register [2]=pgNum(>=4),[3]=Reg,//[4]read_Reg_Num
			HF_MIPI_Read(pdev,ep_addr,SigMode,channel,buffer,LP_B7_Data,HS_B7_Data);
			break;
		case 0x20:	//mulit CMD can send SOLW,SOLR,DSIW,DSIR
			HF_ArrayCMD(pdev,ep_addr,SigMode ,channel,buffer, LP_B7_Data,HS_B7_Data);	
		  break;
	 case 0x30:	//HF demura gen
			//Hefei_Demura_gen(pdev,ep_addr,SigMode ,channel,buffer, LP_B7_Data,HS_B7_Data);	
	 		 break;
	 case 0x32:	//HF demura End
			//Hefei_Demura_End(pdev,ep_addr,SigMode ,channel,buffer, LP_B7_Data,HS_B7_Data);	
		  break;
		default:break;
	}	
	
}
/*
HF_DSI_ArrayWrite(pdev,ep_addr,SigMode ,channel,buffer, LP_B7_Data,HS_B7_Data);
	[0]-6A HF_gen
	[1]-10 arrarwiter
	[2] packagelength=[2]
  [3]-subpacklong
  [4]-subID -{ 00 delay ms
               02 solw  [5]-Reg [6] par1...parnum=subpacklong-3
               04 solR [5]-Reg  [6] R1 [7]-R2 ...parnum=subpacklong-3
							 06 DSIw  [5]-Reg [6] par1...parnum=subpacklong-3
               08 DSIR [5]-Reg  [6] R1 [7]-R2 ...parnum=subpacklong-3
*/




 


